function Cube () {
  this.blocks = []
}

Cube.prototype = {
  clone (cube) {
    for (let block of cube.blocks) {
      this.blocks.push(new Block(new Vector(block.position.x, block.position.y, block.position.z),
        new Vector(block.color.x, block.color.y, block.color.z)))
    }
  },
  init () {
    //添加角块
    // f: 1, r:1, u: 1,
    let fru = new Block(new Vector(1, 1, 1), new Vector(Color.blue, Color.red, Color.yellow))
    let frd = new Block(new Vector(1, 1, -1), new Vector(Color.blue, Color.red, -Color.white))
    let flu = new Block(new Vector(1, -1, 1), new Vector(Color.blue, -Color.orange, Color.yellow))
    let fld = new Block(new Vector(1, -1, -1), new Vector(Color.blue, -Color.orange, -Color.white))
    let bru = new Block(new Vector(-1, 1, 1), new Vector(-Color.green, Color.red, Color.yellow))
    let brd = new Block(new Vector(-1, 1, -1), new Vector(-Color.green, Color.red, -Color.white))
    let blu = new Block(new Vector(-1, -1, 1), new Vector(-Color.green, -Color.orange, Color.yellow))
    let bld = new Block(new Vector(-1, -1, -1), new Vector(-Color.green, -Color.orange, -Color.white))
    this.blocks.push(fru, frd, flu, fld, bru, brd, blu, bld)
  },
  getBlockByPosition (position) {
    for (let block of this.blocks) {
      if (block.position.equals(position))
        return block
    }
    return null
  },
  getFace (faceName) {
    let face = []
    switch (faceName) {
      case 'up': {
        for (let i = 0; i < this.blocks.length; i++) {
          if (this.blocks[i].position.z === 1) {
            let p = this.blocks[i].position
            face[(p.x + 1) + (p.y + 1) / 2] = (this.blocks[i].color.z)
          }
        }
        break
      }
      case 'down': {
        for (let i = 0; i < this.blocks.length; i++) {
          if (this.blocks[i].position.z === -1) {
            let p = this.blocks[i].position
            face[(-p.x + 1) + (p.y + 1) / 2] = (-this.blocks[i].color.z)
          }
        }
        break
      }
      case 'left': {
        for (let i = 0; i < this.blocks.length; i++) {
          if (this.blocks[i].position.y === -1) {
            let p = this.blocks[i].position
            face[(-p.z + 1) + (p.x + 1) / 2] = (-this.blocks[i].color.y)
          }
        }
        break
      }
      case 'right': {
        for (let i = 0; i < this.blocks.length; i++) {
          if (this.blocks[i].position.y === 1) {
            let p = this.blocks[i].position
            face[(-p.z + 1) + (-p.x + 1) / 2] = (this.blocks[i].color.y)
          }
        }
        break
      }
      case 'front': {
        for (let i = 0; i < this.blocks.length; i++) {
          if (this.blocks[i].position.x === 1) {
            let p = this.blocks[i].position
            face[(-p.z + 1) + (p.y + 1) / 2] = (this.blocks[i].color.x)
          }
        }
        break
      }
      case 'behind': {
        for (let i = 0; i < this.blocks.length; i++) {
          if (this.blocks[i].position.x === -1) {
            let p = this.blocks[i].position
            face[(-p.z + 1) + (-p.y + 1) / 2] = (-this.blocks[i].color.x)
          }
        }
        break
      }
    }
    return face
  },
  getLayer (layerName) {
    let blocks = []
    switch (layerName) {
      case 'up': {
        for (let block of this.blocks) {
          if (block.position.z === 1) {
            blocks[block.position.x + 1 + (block.position.y + 1) / 2] = block
          }
        }
      }
        break
      case 'down': {
        for (let block of this.blocks) {
          if (block.position.z === -1) {
            blocks[block.position.x + 1 + (block.position.y + 1) / 2] = block
          }
        }
      }
        break
    }
    return blocks
  },
  rotate (op) {
    if (op === 'x' || op === 'x`') {
      let step = op === 'x' ? 1 : 3
      this.rotateX(step)
      return
    }
    if (op === 'y' || op === 'y`') {
      let step = op === 'y' ? 1 : 3
      this.rotateY(step)
      return
    }
    if (op === 'z' || op === 'z`') {
      let step = op === 'z' ? 1 : 3
      this.rotateZ(step)
      return
    }
    let [dimension, dimValue, step] = patternVector[op]
    for (let i = 0; i < this.blocks.length; i++) {
      this.blocks[i].position[dimension] === dimValue ? this.blocks[i].rotate(Dimension[dimension], step) : doNothing
    }
  },
  rotateZ (step) {
    for (let i = 0; i < this.blocks.length; i++) {
      this.blocks[i].rotate(Dimension.x, step)
    }
  },
  rotateX (step) {
    for (let i = 0; i < this.blocks.length; i++) {
      this.blocks[i].rotate(Dimension.y, step)
    }
  },
  rotateY (step) {
    for (let i = 0; i < this.blocks.length; i++) {
      this.blocks[i].rotate(Dimension.z, step)
    }
  },
  rotatePattern (pattern) {
    var steps = pattern.split(' ')
    for (let step of steps) {
      this.rotate(step)
    }
  }
}

Cube.getOppositeColor = function (color) {
  color = Math.abs(color)
  switch (color) {
    case Color.blue:
      return Color.green
    case Color.green:
      return Color.blue
    case Color.red:
      return Color.orange
    case Color.orange:
      return Color.red
    case Color.yellow:
      return Color.white
    case Color.white:
      return Color.yellow
    default:
      return Color.none
  }
}

const doNothing = 0

